package com.hmyd.hmyd_android.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import com.hmyd.hmyd_android.AppBasic;
import com.hmyd.hmyd_android.ui.SplashScreenActivity;

public class HMYDExceptionHandler implements UncaughtExceptionHandler {

	private Thread.UncaughtExceptionHandler mDefaultHandler;    
	public static final String TAG = "CatchExcep";  

	public HMYDExceptionHandler(){  
		//获取系统默认的UncaughtException处理器    
		mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();  
	}  

	@Override  
	public void uncaughtException(Thread thread, Throwable ex) {
		if(!handleException(ex) && mDefaultHandler != null){   
			//如果用户没有处理则让系统默认的异常处理器来处理    
			mDefaultHandler.uncaughtException(thread, ex);                
		}else{         
			try{    
				Thread.sleep(2000);    
			}catch (InterruptedException e){
				Log.e(TAG, "error : ", e);    
			}     
			// 保存异常信息
			saveCatchInfo2File(ex);

			Intent intent = new Intent(AppBasic.getContextObject(), SplashScreenActivity.class);  
			PendingIntent restartIntent = PendingIntent.getActivity(    
					AppBasic.getContextObject(), 0, intent,    
					Intent.FLAG_ACTIVITY_NEW_TASK);                                                 
			//退出程序                                          
			AlarmManager mgr = (AlarmManager)AppBasic.getContextObject().getSystemService(Context.ALARM_SERVICE);    
			mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000,    
					restartIntent); // 1秒钟后重启应用   
			AppBasic.getInstance().exitSystem(); 
		}    
	}  

	/**  
	 * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.  
	 *   
	 * @param ex  
	 * @return true:如果处理了该异常信息;否则返回false.  
	 */    
	private boolean handleException(Throwable ex) {    
		if (ex == null) {    
			return false;    
		}    
		//使用Toast来显示异常信息    
		new Thread(){    
			@Override    
			public void run() {    
				Looper.prepare();

				Toast.makeText(AppBasic.getContextObject(), "很抱歉,程序出现异常,即将退出.",   
						Toast.LENGTH_SHORT).show();    

				Looper.loop();    
			}   
		}.start();    
		return true;    
	}    

	/** 
	 * 保存错误信息到文件中 
	 *  
	 * @return 返回文件名称 
	 */  
	private String saveCatchInfo2File(Throwable ex) {  
		Writer writer = new StringWriter();  
		PrintWriter printWriter = new PrintWriter(writer);  
		ex.printStackTrace(printWriter);  
		Throwable cause = ex.getCause();  
		while (cause != null) {  
			cause.printStackTrace(printWriter);  
			cause = cause.getCause();  
		}  
		printWriter.close();  
		String sb = writer.toString();  
		try {  
			DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");  
			String time = formatter.format(new Date());  
			String fileName = time + ".txt";  
			System.out.println("fileName:" + fileName);  
			if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 
				String filePath = Environment.getExternalStorageDirectory() + "/hmyd/" + AppBasic.getContextObject().getPackageName()  
						+ "/crash/";  
				File dir = new File(filePath);  
				if (!dir.exists()) {  
					if (!dir.mkdirs()) {  
						// 创建目录失败: 一般是因为SD卡被拔出了  
						return "";  
					}  
				}  
				System.out.println("filePath + fileName:" + filePath + fileName);  
				FileOutputStream fos = new FileOutputStream(filePath + fileName);  
				fos.write(sb.getBytes());  
				fos.close();  
				//文件保存完了之后,在应用下次启动的时候去检查错误日志,发现新的错误日志,就发送给开发者  
			}  
			return fileName;  
		} catch (Exception e) {  
			System.out.println("an error occured while writing file..." + e.getMessage());  
		}  
		return null;  
	}
}
